#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QSize>
#include <QLabel>
#include <QUrl>
#include <QMediaPlaylist>
#include <QTransform>


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //将视图的基类设置为窗口
    mGameview.setParent(this);

    //初始化跳跃的相关数据
    isJumping = false;
    arriveMax = false;
    maxJumpHeight = 90;
    jumpHeight = 0;
    LeapSpeed = 30;
    roleGroundY = 210;

    // 禁用滚动条
    mGameview.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    mGameview.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    // 调整视图大小与场景一致
    mGameview.setFixedSize(1280, 718);

    //设定视图和场景
    mGameview.setSceneRect(QRect(0,0,1280,718));
    mStartScene.setSceneRect(QRect(0,0,1280,718));

    // 创建并设置媒体播放器
    mStartMediaBG = new QMediaPlayer(this);
    mStartMediaBG1 = new QMediaPlayer(this);

    mStartMediaBG1->setMedia(QUrl("qrc:/music/跑酷游戏/音乐/我是奶龙，我才是奶龙_爱给网_aigei_com.mp3"));
    mStartMediaBG->setMedia(QUrl("qrc:/music/跑酷游戏/音乐/春日活力 轻松俏皮_爱给网_aigei_com.mp3"));
    mStartMediaBG->setVolume(50);
    mStartMediaBG1->setVolume(50);

    //音乐循环播放间隔时间计时器
    BGPlayTimer = new QTimer;
    connect(BGPlayTimer,&QTimer::timeout,[this](){
        mStartMediaBG->play();
        mStartMediaBG1->play();
        BGPlayTimer->stop();
    });


    //设置音乐的循环播放
    QObject::connect(mStartMediaBG, &QMediaPlayer::mediaStatusChanged, [=](QMediaPlayer::MediaStatus status) {
            if (status == QMediaPlayer::EndOfMedia) {
                // 当音乐播放结束时，重新开始播放
                BGPlayTimer->start(5000);
            }
        });

    QObject::connect(mStartMediaBG1, &QMediaPlayer::mediaStatusChanged, [=](QMediaPlayer::MediaStatus status) {
            if (status == QMediaPlayer::EndOfMedia) {
                // 当音乐播放结束时，重新开始播放
                BGPlayTimer->start(50000);
            }
        });

    //设置背景图的移动 使背景图处在移动的状态中，而使人物处在移动的假象中
    mBGmoveTimer = new QTimer;
    mBGmoveTimer->start(100);
    connect(mBGmoveTimer,&QTimer::timeout,this,&Widget::BGmove);//每100ms背景图移动一次

    //设置人物移动的计时器操作人物移动
    mRoleMoveTimer = new QTimer;
    mRoleMoveTimer->start(100);
    connect(mRoleMoveTimer,&QTimer::timeout,this,&Widget::mRoleMove);

    //设置跳跃计时器
    jumpTimer = new QTimer;
    jumpTimer->setInterval(100);
    connect(jumpTimer,&QTimer::timeout,this,&Widget::jump);

    //进行游戏开始场景的加载
    LoadStartScene();
}

Widget::~Widget()
{
    delete ui;
}
void Widget::LoadStartScene()
{
    //固定窗口的大小（游戏开始及设置、说明界面）
     this->resize(1280,718);
    //设定游戏背景图，并完成元素——>场景——>视图——>窗口
    mStartBackGround.setPixmap(QPixmap(":/Icon/跑酷游戏/图片/startscene2.jpg"));
    mStartScene.addItem(&mStartBackGround);//背景元素添加到场景中

    //设定游戏名字
    QPixmap pixmap(":/Icon/跑酷游戏/图片/Line.png");
    mStartLine.setPixmap(pixmap);
    mStartLine.setPos(310,-25);
    mStartScene.addItem(&mStartLine);

    QLabel* LineLabel = new QLabel;
    LineLabel->setText("跑酷");
    LineLabel->setFont(QFont("方正舒体",120,7,false));
    LineLabel->setStyleSheet("QLabel{color:#F15C21;background-color:transparent;}");
    LineLabel->resize(500,180);
    LineLabel->move(900,70);

    //将label添加到开始游戏的场景中
    mStartScene.addWidget(LineLabel);


    //设定开始游戏场景的人物
    mStartBGrole.setPixmap(QPixmap(":/Icon/跑酷游戏/图片/startrole.png"));
    mStartBGrole.setPos(50,180);
    mStartScene.addItem(&mStartBGrole);

    mGameview.setScene(&mStartScene);
    mGameview.update();
    mGameview.show();

   //设定开始游戏按钮
    QPushButton* startBtn=new QPushButton;
    startBtn->setText("开始游戏");//设置文本
    startBtn->setFont(QFont("华文琥珀",26,5,false));//设置字体、字体大小、加粗效果、是否倾斜
    startBtn->setStyleSheet("QPushButton{color:black;background-color:#CD853F;}");//设置背景为透明，字体为棕色
    startBtn->resize(275,75);//设置大小
    startBtn->move(750,400);
    mStartScene.addWidget(startBtn);

    //设置游戏说明按钮
    QPushButton* gameInterpretBtn=new QPushButton;
    gameInterpretBtn->setText("游戏说明");//设置文本
    gameInterpretBtn->setFont(QFont("华文琥珀",26,5,false));//设置字体、字体大小、加粗效果、是否倾斜
    gameInterpretBtn->setStyleSheet("QPushButton{color:black;background-color:#CD853F;}");//设置背景为透明，字体为棕色
    gameInterpretBtn->resize(275,75);//设置大小
    gameInterpretBtn->move(750,500);
    mStartScene.addWidget(gameInterpretBtn);

    //设置游戏设置按钮
    QPushButton* installBtn=new QPushButton;
    installBtn->setText("游戏设置");//设置文本
    installBtn->setFont(QFont("华文琥珀",26,5,false));//设置字体、字体大小、加粗效果、是否倾斜
    installBtn->setStyleSheet("QPushButton{color:black;background-color:#CD853F;}");//设置背景为透明，字体为棕色
    installBtn->resize(275,75);//设置大小
    installBtn->move(750,600);
    mStartScene.addWidget(installBtn);

    //点击游戏说明按钮跳转到游戏说明场景（规则、玩法）
    connect(gameInterpretBtn,&QPushButton::clicked,[this](){
        LoadInterpretScene();
    });

    //点击游戏设置按钮跳转到游戏设置场景
    connect(installBtn,&QPushButton::clicked,[this](){
        LoadInstallScene();
    });

    //点击游戏开始按钮跳转到游戏场景
    connect(startBtn,&QPushButton::clicked,[this](){
        LoadGameScene();
    });

}

void Widget::LoadInterpretScene()
{
    //将游戏说明场景赋给视图
    mGameview.setScene(&mGameInterpretScene);
    mGameview.update();
    mGameview.show();

    //设置游戏说明背景图片
    mGameInterpretBackGround.setPixmap(QPixmap(":/Icon/跑酷游戏/图片/startscene2.jpg"));
    mGameInterpretScene.addItem(&mGameInterpretBackGround);

    //设置游戏说明中的游戏规则
    QLabel* gameInterpret1 = new QLabel("游戏操作说明： ");
    gameInterpret1->setStyleSheet("color:black;background:transparent;");//设置背景颜色
    gameInterpret1->setFont(QFont("华文琥珀", 35,10));
    gameInterpret1->resize(400,100);
    gameInterpret1->move(100,125);
    gameInterpret1->show();
    mGameInterpretScene.addWidget(gameInterpret1);

    QLabel* gameInterpret2 = new QLabel;
    gameInterpret2->setText("1.使用键盘和鼠标控制游戏人物的移动：A键控制人物左移、D键控\n制人物右移，点击鼠标右键控制人物跃起。\n"
                            "2.本游戏采用积分制，玩家控制游戏人物每吞吃掉一个硬币积两分，\n每收集一个道具积五分。\n"
                            "3.玩家获得道具会有额外的能力，如加速、免疫伤害等。\n"
                            "4.当玩家控制的角色撞击到障碍物或者掉入沟壑后，游戏结束，显示\n玩家的最后得分。玩家可选择重新开始游戏或者退出。\n");
    gameInterpret2->setStyleSheet("color: Black; background: transparent;");//设置背景颜色
    gameInterpret2->setFont(QFont("华文琥珀", 25,10));
    gameInterpret2->resize(1100,400);
    gameInterpret2->move(140,200);
    gameInterpret2->show();
    mGameInterpretScene.addWidget(gameInterpret2);

    //设置返回游戏开始场景的按钮
    QPushButton* backBtn = new QPushButton;
    backBtn->setText("返回");
    backBtn->setFont(QFont("华文琥珀",26,5,false));//设置字体、字体大小、加粗效果、是否倾斜
    backBtn->setStyleSheet("QPushButton{color:black;background-color:#CD853F;}");//设置背景为透明，字体为棕色
    backBtn->resize(275,75);//设置大小
    backBtn->move(900,25);
    mGameInterpretScene.addWidget(backBtn);
    connect(backBtn,&QPushButton::clicked,[this](){
        LoadStartScene();
    });

}

void Widget::LoadInstallScene()
{
    //将游戏说明场景赋给视图
    mGameview.setScene(&mGameInstallScene);
    mGameview.update();
    mGameview.show();

    //为游戏设置附图片
    mGameInstallBackground.setPixmap(QPixmap(":/Icon/跑酷游戏/图片/startscene2.jpg"));
    mGameInstallScene.addItem(&mGameInstallBackground);

    //设置返回游戏开始场景的按钮
    QPushButton* backBtn1 = new QPushButton;
    backBtn1->setText("返回");
    backBtn1->setFont(QFont("华文琥珀",26,5,false));//设置字体、字体大小、加粗效果、是否倾斜
    backBtn1->setStyleSheet("QPushButton{color:black;background-color:#CD853F;}");//设置背景为透明，字体为棕色
    backBtn1->resize(275,75);//设置大小
    backBtn1->move(950,25);
    mGameInstallScene.addWidget(backBtn1);
    connect(backBtn1,&QPushButton::clicked,[this](){
        LoadStartScene();
    });


    //设置音乐播放的设置标签说明
    QLabel* musicLabel = new QLabel;
    musicLabel->setText("音乐设置:");
    musicLabel->move(130,320);
    musicLabel->resize(190,75);
    musicLabel->setStyleSheet("QLabel{color:black;background-color:transparent;}");
    musicLabel->setFont(QFont("华文琥珀",28,5,false));
    mGameInstallScene.addWidget(musicLabel);//添加到游戏设置场景中

    //设置控制音乐播放的按钮
    QPushButton* musicStartBtn = new QPushButton;
    musicStartBtn->setText("播放音乐");
    musicStartBtn->setFont(QFont("华文琥珀",26,5,false));
    musicStartBtn->setStyleSheet("QPushButton{color:black;background-color:#CD853F;}");
    musicStartBtn->resize(275,75);
    musicStartBtn->move(350,290);
    musicStartBtn->show();
    mGameInstallScene.addWidget(musicStartBtn);//添加到游戏设置场景中

    //设置停止播放音乐的按钮
    QPushButton* musicEndBtn = new QPushButton;
    musicEndBtn->setText("停止播放");
    musicEndBtn->setFont(QFont("华文琥珀",26,5,false));
    musicEndBtn->setStyleSheet("QPushButton{color:black;background-color:#CD853F;}");
    musicEndBtn->resize(275,75);
    musicEndBtn->move(350,390);
    musicEndBtn->show();
    mGameInstallScene.addWidget(musicEndBtn);//添加到游戏设置场景中


    //点击开始播放按钮，播放背景音乐
    connect(musicStartBtn,&QPushButton::clicked,[this](){
        mStartMediaBG1->play();
        mStartMediaBG->play();
    });

    //点击停止播放按钮，停止播放音乐
    connect(musicEndBtn,&QPushButton::clicked,[this](){
       mStartMediaBG1->stop();
       mStartMediaBG->stop();
    });

    //设置音乐音量调节的滑动条
    musicSlider = new QSlider(Qt::Horizontal);
    musicSlider->setRange(0, 100); // 设置滑动条范围为 0 到 100
    musicSlider->move(370,550);

    //设置显示所调节音量的滑动条
    QLabel* valueLabel = new QLabel;
    valueLabel->setText("当前音量：");
    valueLabel->move(130,520);
    valueLabel->resize(190,75);
    valueLabel->setStyleSheet("QLabel{color:black;background-color:transparent;}");
    valueLabel->setFont(QFont("华文琥珀",28,5,false));

    // 连接滑动条的 valueChanged 信号到槽函数
    connect(musicSlider, &QSlider::valueChanged, this, &Widget::MusicVolumeSet);

    mGameInstallScene.addWidget(valueLabel);//添加到游戏设置场景中
    mGameInstallScene.addWidget(musicSlider);

}

void Widget::LoadGameScene()
{
    //重新设置窗口的大小
    this->resize(1280,510);

    //将游戏场景赋给视图
    mGameview.setScene(&mGameScene);
    mGameview.update();
    mGameview.show();

    //为背景图片设置位置，并且给与资源路径
    QPixmap gameScenePixmap(":/Icon/跑酷游戏/图片/Game1.jpg");
    QPixmap _gameScenePixmap=gameScenePixmap.scaled(1280,510);//重新设置照片的大小

    mGameBackGround1.setPixmap(_gameScenePixmap);//将照片传给背景图
    mGameBackGround2.setPixmap(_gameScenePixmap);

    mGameBackGround1.setPos(0,0);
    mGameBackGround2.setPos(1280,0);//设置背景图位置
    mGameScene.addItem(&mGameBackGround2);
    mGameScene.addItem(&mGameBackGround1);

    //设定游戏人物
    QPixmap _rolePixmap1(":/Icon/跑酷游戏/图片/奶龙素材PNG (2)_爱给网_aigei_com.png");//人物正常行走时的形象
    QPixmap _rolePixmap2(":/Icon/跑酷游戏/图片/nailongRoleLeap.png");//人物跳跃时的形象
    //重新设定游戏人物的大小
    QPixmap rolePixmap1=_rolePixmap1.scaled(100,108);
    QPixmap rolePixmap2=_rolePixmap1.scaled(100,133);

    //为游戏人物设置图片，并将游戏人物传给游戏场景
    mRole.setPixmap(rolePixmap1);
    mRole.setPos(130,210);
    mGameScene.addItem(&mRole);

    //将游戏人物镜像翻转
    QTransform transform;
    transform.scale(-1, 1); // 水平方向缩放因子为 -1 实现水平翻转，垂直方向缩放因子为 1 保持不变
    mRole.setTransform(transform);


    //设置返回游戏开始场景的按钮
    QPushButton* backBtn2 = new QPushButton;
    backBtn2->setText("返回");
    backBtn2->setFont(QFont("华文琥珀",26,5,false));//设置字体、字体大小、加粗效果、是否倾斜
    backBtn2->setStyleSheet("QPushButton{color:black;background-color:transparent;}");//设置背景为透明，字体为棕色
    backBtn2->resize(275,75);//设置大小
    backBtn2->move(1050,12);
    mGameScene.addWidget(backBtn2);
    backBtn2->show();
    connect(backBtn2,&QPushButton::clicked,[this](){
        LoadStartScene();
    });

}

//设置滑动条控制音量
void Widget::MusicVolumeSet(int value)
{
    mStartMediaBG->setVolume(value);
    mStartMediaBG1->setVolume(value);
}

//设置游戏界面背景图移动函数
void Widget::BGmove()
{
    mGameBackGround1.moveBy(-7,0);
    mGameBackGround2.moveBy(-7,0);

    if(mGameBackGround1.x() + 1280 <= 0){
        mGameBackGround1.setX(1280);
    }
    else if(mGameBackGround2.x() + 1280 <= 0){
        mGameBackGround2.setX(1280);
    }
}

//设置人物移动函数
void Widget::mRoleMove(){
    for(int keyCode:mKeyList)
    {
        switch(keyCode)
        {
        case Qt::Key_D: mRole.moveBy(3,0);break;
        case Qt::Key_A: mRole.moveBy(-3,0);break;
        }
    }

    //边界的设置：倘若人物碰到边界，则返回，使人物不出界
    if(mRole.x()<0)
    {
        mRole.setX(0);
    }
    else if(mRole.x()>1280)
    {
        mRole.setX(1280);
    }
    else if(mRole.y()<0)
    {
        mRole.setY(0);
    }
    else if(mRole.y()>300)
    {
        mRole.setY(300);
    }
}

//设置键盘事件
void Widget::keyPressEvent(QKeyEvent* event){
    switch(event->key())
    {
        case Qt::Key_D:
        {
           mKeyList.append(event->key());
           break;
        }
        case Qt::Key_A:
        {
           mKeyList.append(event->key());
           break;
        }
        case Qt::Key_Space:
        {
           if(!isJumping)
           {
               jumpHeight = roleGroundY;
               isJumping = true;
               arriveMax = false;
               jumpTimer->start();
           }
           break;
        }
    }
}

void Widget::keyReleaseEvent(QKeyEvent *event){
    if(mKeyList.contains(event->key()))
    {
        mKeyList.removeOne(event->key());
    }
}

//跳跃函数
void Widget::jump(){
    if(isJumping)
    {
        //倘若未能达到最大高度，则不断上升
        if(jumpHeight >= maxJumpHeight){
            jumpHeight -= LeapSpeed;
            mRole.setY(jumpHeight);
        }
        //如果小于最大高度，则往下移
        if(jumpHeight <= maxJumpHeight - 10 )
        {
            arriveMax = true;
        }

        if(arriveMax)
        {
            jumpHeight += LeapSpeed;
            mRole.setY(jumpHeight);
        }
        //倘若达到和地面同一高度，则停止移动
        if (jumpHeight >= roleGroundY + 1)
        {
            mRole.setY(roleGroundY);
            arriveMax = false;
            isJumping = false;
            jumpTimer->stop();
        }
    }
}
